package com.xr.util;

import java.util.Collection;
import java.util.Map;

/**
 * Assertion utility class that assists in validating arguments.
 *
 * <p>Useful for identifying programmer errors early and clearly at runtime.
 *
 * <p>For example, if the contract of a public method states it does not
 * allow {@code null} arguments, {@code Assert} can be used to validate that
 * contract. Doing this clearly indicates a contract violation when it
 * occurs and protects the class's invariants.
 *
 * <p>Typically used to validate method arguments rather than configuration
 * properties, to check for cases that are usually programmer errors rather
 * than configuration errors. In contrast to configuration initialization
 * code, there is usually no point in falling back to defaults in such methods.
 *
 * <p>This class is similar to JUnit's assertion library. If an argument value is
 * deemed invalid, an {@link IllegalArgumentException} is thrown (typically).
 * For example:
 *
 * <pre class="code">
 * Assert.notNull(clazz, "The class must not be null");
 * Assert.isTrue(i > 0, "The value must be greater than zero");</pre>
 *
 * <p>Mainly for internal use within the framework; consider
 * <a href="http://commons.apache.org/proper/commons-lang/">Apache's Commons Lang</a>
 * for a more comprehensive suite of {@code String} utilities.
 *
 * @author Keith Donald
 * @author Juergen Hoeller
 * @author Sam Brannen
 * @author Colin Sampaleanu
 * @author Rob Harrop
 * @since 1.1.2
 */
public abstract class Assert {

  /**
   * Assert a boolean expression, throwing an {@code IllegalArgumentException}
   * if the expression evaluates to {@code false}.
   * <pre class="code">Assert.isTrue(i &gt; 0, "The value must be greater than zero");</pre>
   * @param expression a boolean expression
   * @param message the exception message to use if the assertion fails
   * @throws IllegalArgumentException if {@code expression} is {@code false}
   */
  public static void isTrue(boolean expression, String message) {
    if (!expression) {
      throw new IllegalArgumentException(message);
    }
  }

  /**
   * Assert that an object is {@code null}.
   * <pre class="code">Assert.isNull(value, "The value must be null");</pre>
   * @param object the object to check
   * @param message the exception message to use if the assertion fails
   * @throws IllegalArgumentException if the object is not {@code null}
   */
  public static void isNull(Object object, String message) {
    if (object != null) {
      throw new IllegalArgumentException(message);
    }
  }

  /**
   * Assert that an object is not {@code null}.
   * <pre class="code">Assert.notNull(clazz, "The class must not be null");</pre>
   * @param object the object to check
   * @param message the exception message to use if the assertion fails
   * @throws IllegalArgumentException if the object is {@code null}
   */
  public static void notNull(Object object, String message) {
    if (object == null) {
      throw new IllegalArgumentException(message);
    }
  }

  /**
   * Assert that the given String is not empty; that is,
   * it must not be {@code null} and not the empty String.
   * <pre class="code">Assert.hasLength(name, "Name must not be empty");</pre>
   * @param text the String to check
   * @param message the exception message to use if the assertion fails
   * @throws IllegalArgumentException if the text is empty
   */
  public static void hasLength(String text, String message) {
    if (!StringUtil.hasLength(text)) {
      throw new IllegalArgumentException(message);
    }
  }

  /**
   * Assert that the given text does not contain the given substring.
   * <pre class="code">Assert.doesNotContain(name, "rod", "Name must not contain 'rod'");</pre>
   * @param textToSearch the text to search
   * @param substring the substring to find within the text
   * @param message the exception message to use if the assertion fails
   * @throws IllegalArgumentException if the text contains the substring
   */
  public static void doesNotContain(String textToSearch, String substring, String message) {
    if (StringUtil.hasLength(textToSearch) && StringUtil.hasLength(substring) &&
            textToSearch.contains(substring)) {
      throw new IllegalArgumentException(message);
    }
  }

  public static void notEmpty(Collection<?> collection, String message) {
    if (collection == null || collection.isEmpty()) {
      throw new IllegalArgumentException(message);
    }
  }

  public static void notEmpty(Map<?, ?> map, String message) {
    if (map == null || map.isEmpty()) {
      throw new IllegalArgumentException(message);
    }
  }

  public static boolean endsWithSeparator(String msg) {
    return (msg.endsWith(":") || msg.endsWith(";") || msg.endsWith(",") || msg.endsWith("."));
  }

  public static String messageWithTypeName(String msg, Object typeName) {
    return msg + (msg.endsWith(" ") ? "" : ": ") + typeName;
  }

  public static void largeThan(Double a, Double b, String message) {
    notNull(a, "data must not be null");
    notNull(b, "data must not be null");
    if( a <= b){
      throw new IllegalArgumentException(message);
    }
  }

  public static void equals(Object a, Object b, String message) {
    if( a != b){
      throw new IllegalArgumentException(message);
    }
  }

  public static void failedWhenEquals(Object a, Object b, String message) {
    if( a == b){
      throw new IllegalArgumentException(message);
    }
  }

  public static void largeThanZero(Long a, String message) {
    notNull(a, "data must not be null");
    largeThanZero(a.doubleValue(), message);
  }

  public static void largeThanZero(Integer a, String message) {
    notNull(a, "data must not be null");
    largeThanZero(a.doubleValue(), message);
  }

  public static void largeThanZero(Double a, String message) {
    notNull(a, "data must not be null");
    if( a <= 0){
      throw new IllegalArgumentException(message);
    }
  }

  public static void isNumber(Object obj, String message) {
    notNull(obj, "data must not be null");
    try {
      Double.valueOf(obj.toString());
    } catch (NumberFormatException nfe){
      throw new IllegalArgumentException(message);
    }
  }
}
